<?php
/*
 * @Author: 孙开源 && sunkaiyuan@namenode.cn
 * @Date: 2023-04-12 16:45:39
 * @LastEditors: 孙开源 && sunkaiyuan@namenode.cn
 * @LastEditTime: 2023-04-12 17:13:20
 * @Description: 
 * 
 */
namespace szzhijing\Kernel\Traits;

use szzhijing\Kernel\Exceptions\InvalidArgumentException;
use szzhijing\Kernel\Responses\Response;
use szzhijing\Kernel\Support\Collection;
use Psr\Http\Message\ResponseInterface;

 
trait ResponseCastable
    {
    /**
     * @param \Psr\Http\Message\ResponseInterface $response
     * @param string|null                         $type
     *
     * @return array|\szzhijing\Kernel\Support\Collection|object|\Psr\Http\Message\ResponseInterface|string
     */
    protected function castResponseToType(ResponseInterface $response, $type = null)
        {
        if ('raw' === $type) {
            return $response;
            }

        $response = Response::buildFromPsrResponse($response);
        $response->getBody()->rewind();

        switch ($type ?? 'array') {
            case 'collection':
                return $response->toCollection();
            case 'array':
                return $response->toArray();
            case 'object':
                return $response->toObject();
            }
        }

    /**
     * @param mixed       $response
     * @param string|null $type
     *
     * @throws \szzhijing\Kernel\Exceptions\InvalidArgumentException
     *
     * @return array|\szzhijing\Kernel\Support\Collection|object|\Psr\Http\Message\ResponseInterface|string
     */
    protected function detectAndCastResponseToType($response, $type = null)
        {
        switch (true) {
            case $response instanceof ResponseInterface:
                $response = Response::buildFromPsrResponse($response);

                break;
            case ($response instanceof Collection) || is_array($response) || is_object($response):
                $response = new Response(200, [], json_encode($response));

                break;
            case is_scalar($response):
                $response = new Response(200, [], $response);

                break;
            default:
                throw new InvalidArgumentException(sprintf('Unsupported response type "%s"', gettype($response)));
            }

        return $this->castResponseToType($response, $type);
        }
    }